using System;
using System.Collections.Generic;
using DG.Tweening;
using GameFramework.Battle.Core;
using Gameplay.PVE.Skill;
using Gameplay.PVE.Utils;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using Yoozoo.UI;
using Yoozoo.UI.YGUI;
using Random = UnityEngine.Random;

namespace Gameplay.PVE
{  
    public enum ETextColor
    {
        White,
        Yellow,
        Green,
        Red,
        Blue,
    }

    public class PveFlyTextConfig
    {
        public int type;//0 普攻 1 技能
        public Vector3 start;
        public Vector3 startRandom;
        public Vector3 end;
        public Vector3 endRandom;
        public float duration;
        public float scale;
    }

    public class PveFlyTextManager
    {
        private static PveFlyTextManager instance;

        public Dictionary<int, PveFlyTextConfig> configs = new Dictionary<int, PveFlyTextConfig>();

        public bool showFlyText = true; //是否展示文字
        public bool showBloodBar = true; //是否展示血条
        public bool showEffect = true; //是否展示特效

        public static float flyTextRangeX = 0.3f;
        public static float flyTextRangeY = 0.2f;

        public static float flyTextCriticalRangeX = 0.3f;
        public static float flyTextCriticalRangeY = 0.4f;
        
        public static float flyTextSkillRangeX = 0.3f;
        public static float flyTextSkillRangeY = 0.4f;
        
        public static float flyTextAbsorbRangeX = 0.3f;
        public static float flyTextAbsorbRangeY = 0.3f;
        
        private readonly string myCriticalAnim = "ani_pveFlyTextNormal_l_critical";
        private readonly string enemyCriticalAnim = "ani_pveFlyTextNormal_r_critical";
        private readonly string mySkillAnim = "ani_pveFlyTextSkill_l";
        private readonly string enemySkillAnim = "ani_pveFlyTextSkill_r";
        private readonly string myNormalAttackAnim = "ani_pveFlyTextNormal_l";
        private readonly string enemyNormalAttackAnim = "ani_pveFlyTextNormal_r";
        private readonly string myHealAnim = "ani_pveFlyTextHeal_l";
        private readonly string enemyHealAnim = "ani_pveFlyTextHeal_r";
        private readonly string myAbsorbAnim = "ani_pveFlyTextAbsorb_l";
        private readonly string enemyAbsorbAnim = "ani_pveFlyTextAbsorb_r";

        private readonly string comboAniAppearR = "ani_pveFlyTextNormal_r_lj_in";
        private readonly string comboAniDisappearR = "ani_pveFlyTextNormal_r_lj_out";
        private readonly string comboAniAppearL = "ani_pveFlyTextNormal_l_lj_in";
        private readonly string comboAniDisappearL = "ani_pveFlyTextNormal_l_lj_out";
        private readonly string comboTextRefresh = "ani_pveFlyTextNormal_r_lj_zi_in";

        private readonly string elementAnim = "ani_pveFlyTextBuff";

        private GameObject root;
        
        private Dictionary<int, GameObject> storagedFlyText = new Dictionary<int, GameObject>(32);
        private Dictionary<int, float> storagedDamage = new Dictionary<int, float>(32);
        private Dictionary<int, UnitFlyTextData> unitFlyDataDict = new Dictionary<int, UnitFlyTextData>(32);
        private Dictionary<int, int> bulletID2UnitID = new Dictionary<int, int>(32);
        
        private enum EFlyTextType
        {
            selfNormalAttack = 2,
            selfNormalAttackCrit = 3,
            enemyNormalAttack = 4,
            enemyNormalAttackCrit = 5,
            skill = 7,
            skillCrit = 6,
            heal = 8,
            comboNormalAttack = 20,
            common = 21,
            elementSelf = 22,
            elementEnemy = 23,
            Kill2 = 32,
            Kill3 = 33,
            Kill4 = 34,
            Kill5 = 35,
            Kill6 = 36,
        }
        
        public static PveFlyTextManager Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new PveFlyTextManager();
                }

                return instance;
            }

        }

        public PveFlyTextManager()
        {
            InitConfig();
            PveManager.Instance.onBattleFinish += EndAllNormalAttackText;
        }

        public void Init()
        {
            if (root != null)
            {
                return;
            }
            root = new GameObject("[PveFlyTextRoot]");
            root.transform.SetParent(PveScene.pveRootTrans);
            var canvas = root.AddComponent<Canvas>();
            canvas.renderMode = RenderMode.WorldSpace;
            canvas.worldCamera = PveCameraManager.Instance.mainCamera;
        }

        public void Dispose()
        {
            if (root != null)
            {
                GameObject.Destroy(root);
                root = null;
            }

            PveManager.Instance.onBattleFinish -= EndAllNormalAttackText;
        }

        private SkillBase blackScreenSkill;
        private List<GameObject> hiddenFlyTextObjects = new List<GameObject>();

        public void SetLayer(int layer)
        {
            if (root)
            {
                root.SetLayerRecursively(layer);
            }
        }
        
        public void StartSkillBlackScreen(SkillBase skill)
        {
            if (blackScreenSkill != null)
            {
                EndSkillBlackScreen();
            }
            blackScreenSkill = skill;
            hiddenFlyTextObjects.Clear();
            
            var transform = root.transform;
            var childCount = transform.childCount;
            for (int i = 0; i < childCount; i++)
            {
                var flyText = transform.GetChild(i);
                var obj = flyText.gameObject;
                obj.SetActive(false);
                hiddenFlyTextObjects.Add(obj);
            }
        }

        public void EndSkillBlackScreen()
        {
            blackScreenSkill = null;
            for (int i = 0; i < hiddenFlyTextObjects.Count; i++)
            {
                var obj = hiddenFlyTextObjects[i];
                if (obj)
                {
                    obj.SetActive(true);
                }
            }
            hiddenFlyTextObjects.Clear();
        }
        
        public void RefreshRootForward(Vector3 forward)
        {
            this.root.transform.forward = forward;
        }

        private void InitConfig()
        {
            configs.Add(0, new PveFlyTextConfig
            {
                type = 0,
                start = new Vector3(0, 1.5f, 0),
                startRandom = new Vector3(0.3f, 0.3f, 0),
                end = new Vector3(0.3f, 0.5f, 0.3f),
                endRandom = new Vector3(0.1f, 0, 0.1f),
                duration = 0.2f,
                scale = 2f,
            });
            configs.Add(1, new PveFlyTextConfig
            {
                type = 1,
                start = new Vector3(0, 1, 0),
                startRandom = new Vector3(0.5f, 0.2f, 0f),
                end = new Vector3(0.8f, 0.5f, 0.8f),
                endRandom = new Vector3(0.1f, 0, 0.1f),
                duration = 0.2f,
                scale = 2,
            });
            configs.Add(2,new PveFlyTextConfig
            {
                type = 2,
                start = new Vector3(0,1,0),
                startRandom = new Vector3(0.3f, 0.2f, 0.3f),
                end = new Vector3(0.2f, 0.5f, 0.2f),
                endRandom = new Vector3(0.1f, 0, 0.1f),
                duration = 0.2f,
                scale = 1.5f,
            });
        }

        private bool CheckNeedCullByBlackScreenSkill(SkillBase skill)
        {
            if (blackScreenSkill == null)
            {
                return false;
            }
            return blackScreenSkill != skill;
        }
        
        public void ShowHealFlyText(int number, Vector3 position, int team, int unitID,SkillBase skill)
        {
            if (!showFlyText)
            {
                return;
            }

            if (CheckNeedCullByBlackScreenSkill(skill))
            {
                return;
            }
            
            int flyTextId = (int) EFlyTextType.heal;
            var ani = team == 2 ? myHealAnim : enemyHealAnim;
            var text = PveResourceManager.GetResource(PveResourceManager.EPveResType.Hud, flyTextId);
            if (text != null)
            {
                var t = text.transform;
                t.SetParent(this.root.transform);
                t.position = position;
                t.localEulerAngles = Vector3.zero;
                t.localPosition += new Vector3(Random.Range(-flyTextRangeX, flyTextRangeX),
                    Random.Range(-flyTextRangeY, flyTextRangeY), GetFlyTextZOffset(AddToLayerMgr(unitID)));
                
                var textCom = text.GetComponentInChildren<TextMeshPro>();
                textCom.text = number.ToString();
                
                var animation = text.GetComponent<Animation>();
                animation.Play(ani);
                
                DelayCall(2000, () =>
                {
                    RemoveFromLayerMgr(unitID);
                    PveResourceManager.RecoverResource(text, PveResourceManager.EPveResType.Hud, flyTextId);
                });
            }
        }

        public void ShowFlyTextKill(int killNum, Vector3 position, int unitID)
        {
            if (!showFlyText)
            {
                return;
            }

            
            int id = 30 + killNum;
            if (id > 36)
            {
                id = 36;
            }
            var text = PveResourceManager.GetResource(PveResourceManager.EPveResType.Hud, id);
            if (text)
            {
                var t = text.transform;
                t.SetParent(this.root.transform);
                t.position = position;
                t.localPosition += new Vector3(0, 0, GetFlyTextZOffset(AddToLayerMgr(unitID)));
                t.localEulerAngles = Vector3.zero;
                t.localScale = new Vector3(0.015f,0.015f,0.015f);
                DelayCall(2000, () =>
                {
                    RemoveFromLayerMgr(unitID);
                    PveResourceManager.RecoverResource(text, PveResourceManager.EPveResType.Hud,
                        id);
                });
            }
        }

        private void ShowFlyTextById(string content, Vector3 position, int unitID, int team, EFlyTextType type,
            bool random = true, SkillBase skill = null)
        {
            if (!showFlyText)
            {
                return;
            }
            if (CheckNeedCullByBlackScreenSkill(skill))
            {
                return;
            }
            int resId = (int) type;
            var _text = PveResourceManager.GetResource(PveResourceManager.EPveResType.Hud, resId);
            if (!_text)
            {
                return;
            }
            var t = _text.transform;
            t.SetParent(this.root.transform);
            t.position = position;
            Vector3 offset;
            if (random)
            {
                offset = new Vector3(Random.Range(-flyTextRangeX, flyTextRangeX),
                    Random.Range(-flyTextRangeY, flyTextRangeY), GetFlyTextZOffset(AddToLayerMgr(unitID)));
            }
            else
            {
                offset = new Vector3(0,0,GetFlyTextZOffset(AddToLayerMgr(unitID)));
            }
            t.localPosition += offset;
            t.localEulerAngles = Vector3.zero;
            var tmp = _text.transform.Find("zong/Text").GetComponent<TextMeshPro>();
            tmp.text = content;
            _text.GetComponent<Animation>()?.Play(team == 0 ? this.comboAniAppearR : this.comboAniAppearL);
            _text.transform.Find("zong")?.GetComponent<Animation>()?.Play(this.comboTextRefresh);
            
            DelayCall(500, () =>
            {
                if (_text == null)
                    return;
               
                _text.GetComponent<Animation>()?.Play(team == 0
                    ? this.comboAniDisappearR
                    : this.comboAniDisappearL);

                DelayCall(1000, () =>
                {
                    RemoveFromLayerMgr(unitID);
                    PveResourceManager.RecoverResource(_text, PveResourceManager.EPveResType.Hud,
                        resId);
                });
            });

        }

        public void ShowFlyTextElement(string content, Vector3 position, int unitID, int sourceTeam,SkillBase skill)
        {
            if (!showFlyText)
            {
                return;
            }

            if (CheckNeedCullByBlackScreenSkill(skill))
            {
                return;
            }
            int resId = sourceTeam == 0 ? (int) EFlyTextType.elementSelf : (int) EFlyTextType.elementEnemy;
            var _text = PveResourceManager.GetResource(PveResourceManager.EPveResType.Hud, resId);
            if (!_text)
            {
                return;
            }
            var t = _text.transform;
            t.SetParent(this.root.transform);
            t.position = position;
            Vector3 offset = new Vector3(0,0,GetFlyTextZOffset(AddToLayerMgr(unitID)));
            t.localPosition += offset;
            t.localEulerAngles = Vector3.zero;
            var tmp = _text.transform.Find("zong/Text").GetComponent<TextMeshPro>();
            tmp.text = content;
            _text.GetComponent<Animation>()?.Play(elementAnim);
            DelayCall(1500, () =>
            {
                RemoveFromLayerMgr(unitID);
                PveResourceManager.RecoverResource(_text, PveResourceManager.EPveResType.Hud,
                    resId);
            });
        }
        
        
        public void ShowFlyTextCommon(string content, Vector3 position,int unitID,int team,SkillBase skill = null)
        {
            if (CheckNeedCullByBlackScreenSkill(skill))
            {
                return;
            }
            ShowFlyTextById(content,position,unitID,team,EFlyTextType.common,true,skill);
        }

        public void ShowBlockFlyText(Vector3 position, int unitID, int team)
        {
            return;
            ShowFlyTextCommon(PveUtils.GetLangText("RPG_Battle_Fly_Text_Block"), position, unitID, team);
        }
        
        public void ShowAbsorbFlyText(string number,Vector3 position, int unitID, int team,SkillBase skill)
        {
            ShowFlyTextCommon(PveUtils.GetLangText("RPG_Battle_Fly_Text_Resist"), position, unitID, team,skill);
        }
        
        public void ShowImmuneFlyText(Vector3 position, int unitID, int team)
        {
            return;
            ShowFlyTextCommon(PveUtils.GetLangText("RPG_Battle_Fly_Text_Immune"), position, unitID, team);
        }

        public void ShowMiss(Vector3 position, int unitID, int team)
        {
            ShowFlyTextCommon(PveUtils.GetLangText("RPG_Battle_Fly_Text_Miss"), position, unitID, team);
        }

        private class FlyTextConcat
       {
           public GameObject gameObject;
           public float currentValue;
           public int targetValue;
           public TextMeshPro tmp;
           public Animation animation;
           public float speed;
       }

       private Dictionary<SkillBase, FlyTextConcat> flyTextConcats = new Dictionary<SkillBase, FlyTextConcat>();

       private struct FlyTextData
       {
           public GameObject gameObject;
           public List<float> delayTimes;
           public List<Action> delayActions;
       }

       private struct DelayAction
       {
           public float actionTime;
           public Action action;
       }
       
       private List<FlyTextData> flyTextDataList = new List<FlyTextData>();

       private List<DelayAction> delayActionList = new List<DelayAction>();
       
       private float currentTime;
       private bool isPause = false;
       private float timeScale = 1;
       
       public void Update()
       {
           foreach (var item in flyTextConcats.Values)
           {
               item.currentValue = Mathf.CeilToInt(item.currentValue + item.speed * TimeManager.GameDeltaTime);
               if (item.currentValue >= item.targetValue)
               {
                   item.speed = 0;
               }
               item.tmp.text = item.currentValue.ToString();
           }

           for (int i = 0; i < delayActionList.Count; i++)
           {
               var data = delayActionList[i];
               if (data.actionTime <= currentTime)
               {
                   data.action?.Invoke();
                   delayActionList.RemoveAt(i);
                   i--;
               }
           }
           
           /*for (int i = 0; i < flyTextDataList.Count; i++)
           {
               var data = flyTextDataList[i];
               for (int j = 0; j < data.delayTimes.Count; j++)
               {
                   var delayTime = data.delayTimes[j];
                   if (delayTime >= currentTime)
                   {
                       data.delayActions[j]?.Invoke();
                       data.delayTimes.RemoveAt(j);
                       data.delayActions.RemoveAt(j);
                       j--;
                   }
               }

               if (data.delayTimes.Count == 0)
               {
                   flyTextDataList.RemoveAt(i);
                   i--;
               }
           }*/

           if (!isPause)
           {
               currentTime += Time.unscaledDeltaTime * PveManager.Instance.TimeSpeed;
           }
       }

       public void Pause()
       {
           isPause = true;
       }

       public void Resume()
       {
           isPause = false;
       }
       
       public void SkillEnd(SkillBase skill)
       {
           flyTextConcats.Remove(skill);
       }

       /*public void ShowNormalAttackFlyTextConcat(int number,Vector3 position,SkillBase skill,bool isToSelf)
       {
           if (!showFlyText)
           {
               return;
           }

           FlyTextConcat ftc;
           if (!flyTextConcats.TryGetValue(skill, out ftc))
           {
               var text = PveResourceManager.GetResource(PveResourceManager.EPveResType.Hud, 3);
               if (text != null)
               {
                   text.transform.SetParent(this.root.transform);
                   text.transform.forward = PveCameraManager.Instance.mainCamera.transform.forward;
                   var textCom = text.GetComponentInChildren<TextMeshPro>();
                   text.transform.position = position + new Vector3(Random.Range(-flyTextRangeX, flyTextRangeX),
                                                 Random.Range(-flyTextRangeY, flyTextRangeY), 0); //startPosition;
                   var animation = text.GetComponent<Animation>();

                   ftc = new FlyTextConcat
                   {
                       gameObject = text,
                       animation = animation,
                       tmp = textCom,
                       currentValue = number,
                       targetValue = 0,
                   };
                   
                   flyTextConcats.Add(skill,ftc);
               }
               else
               {
                   return;
               }
               ftc.targetValue += number;
               ftc.animation.Stop();
               ftc.animation.Play(isToSelf ? myNormalAttackAnim : enemyNormalAttackAnim);
               ftc.speed = (ftc.targetValue - ftc.currentValue) / 0.5f;
           }   
       }*/

       /*private string GetSpriteContentByNumber(int number)
       {
           if (number == 0)
           {
               return "<sprite=0>";
           }
           string s = string.Empty;
           while (number > 0)
           {
               s = string.Format("<sprite={0}>{1}", number % 10,s);
               number /= 10;
           }
           return s;
       }*/

       private float criticalSizeRatio = 1.5f;
       private float normalAttackTextInitSize = -1;
       private float normalAttackTextCriticalSize = -1;
       /// <summary>
       /// 显示普攻飘字
       /// </summary>
       /// <param name="uniqueID"></param> 如果等于-1则不合并
       /// <param name="number"></param>
       /// <param name="position"></param>
       /// <param name="attackerTeam"></param>
       /// <param name="isCritical"></param>
       public void ShowNormalAttackFlyText(int uniqueID, float number, Vector3 position, int attackerTeam,
           bool isCritical, int unitID,SkillBase skill)
       {
           if (!showFlyText)
               return;
           
           if (CheckNeedCullByBlackScreenSkill(skill))
           {
               return;
           }
           GameObject _text = null;
           var isNew = false;
           if (uniqueID == -1)
           {
               if (!NewNormalFlyText(unitID, position, out _text))
                   return;

               isNew = true;
           }
           else
           {
               if (this.storagedDamage.ContainsKey(uniqueID))
                   this.storagedDamage[uniqueID] += number;
               else
                   this.storagedDamage.Add(uniqueID, number);
               
               if (!this.storagedFlyText.TryGetValue(uniqueID, out _text))
               {
                   if (!NewNormalFlyText(unitID, position, out _text))
                       return;
                   
                   this.storagedFlyText.Add(uniqueID, _text);
                   this.bulletID2UnitID.Add(uniqueID, unitID);
                   isNew = true;
               }
           }

           var tmp = _text.transform.Find("zong/Text").GetComponent<TextMeshPro>();
           if (Mathf.Approximately(this.normalAttackTextInitSize, -1))
           {
               this.normalAttackTextInitSize = tmp.fontSize;
               this.normalAttackTextCriticalSize = this.normalAttackTextInitSize * this.criticalSizeRatio;
           }

           if (uniqueID == -1)
           {
               tmp.text = ((int) number).ToString();
               DelayCall(500, () =>
               {
                   if (_text == null)
                       return;
                   
                   _text.GetComponent<Animation>()?.Play(PveBattleBulletsMgr.Ins.GetTeamByBulletID(uniqueID) == 0
                       ? this.comboAniDisappearR
                       : this.comboAniDisappearL);
                   DelayCall(1000, () =>
                   {
                       RemoveFromLayerMgr(unitID);
                       PveResourceManager.RecoverResource(_text, PveResourceManager.EPveResType.Hud,
                           (int) EFlyTextType.comboNormalAttack);
                   });
               });
           }
           else
           {
               tmp.text = ((int) this.storagedDamage[uniqueID]).ToString();
           }
           
           var size = isCritical ? this.normalAttackTextCriticalSize : this.normalAttackTextInitSize;
           if (isNew)
           {
               _text.GetComponent<Animation>()?.Play(attackerTeam == 0 ? this.comboAniAppearR : this.comboAniAppearL);
               tmp.fontSize = size;
               if (attackerTeam == 2)
               {
                   tmp.overrideColorTags = true;
                   tmp.colorGradient = new VertexGradient
                   {
                       topLeft = new Color(1,0,0),
                       topRight = new Color(1,0,0),
                       bottomLeft = new Color(60/255f,60/255f,60/255f),
                       bottomRight = new Color(60/255f,60/255f,60/255f),
                   };
               }
               else
               {
                   tmp.overrideColorTags = true;
                   tmp.colorGradient = new VertexGradient
                   {
                       topLeft = new Color(212/255f,212/255f,212/255f),
                       topRight = new Color(212/255f,212/255f,212/255f),
                       bottomLeft = new Color(60/255f,60/255f,60/255f),
                       bottomRight = new Color(60/255f,60/255f,60/255f),
                   };
               }
           }
           else if(tmp.fontSize<size)
               tmp.fontSize = size;

           _text.transform.Find("zong")?.GetComponent<Animation>()?.Play(this.comboTextRefresh);
       }

       private bool NewNormalFlyText(int unitID, Vector3 position, out GameObject go)
       {
           go = PveResourceManager.GetResource(PveResourceManager.EPveResType.Hud,
               (int) EFlyTextType.comboNormalAttack);

           var ret = go != null;
           if (ret)
           {
               var t = go.transform;
               t.SetParent(this.root.transform);
               t.position = position;
               t.localPosition += new Vector3(Random.Range(-flyTextRangeX, flyTextRangeX),
                   Random.Range(-flyTextRangeY, flyTextRangeY), GetFlyTextZOffset(AddToLayerMgr(unitID)));
               t.localEulerAngles = Vector3.zero;
           }

           return ret;
       }

       public void EndNormalAttackText(int uniqueID)
       {
           DelayCall(500, () =>
           {
               if (this.storagedFlyText.ContainsKey(uniqueID))
               {
                   var go = this.storagedFlyText[uniqueID];
                   this.storagedFlyText.Remove(uniqueID);
                   
                   var id = this.bulletID2UnitID[uniqueID];
                   this.bulletID2UnitID.Remove(uniqueID);
                   if (go == null)
                       return;
                   
                   go.GetComponent<Animation>().Play(PveBattleBulletsMgr.Ins.GetTeamByBulletID(uniqueID) == 0
                       ? this.comboAniDisappearR
                       : this.comboAniDisappearL);
                   
                   DelayCall(1000, () =>
                   {
                       RemoveFromLayerMgr(id);
                       PveResourceManager.RecoverResource(go, PveResourceManager.EPveResType.Hud,
                           (int) EFlyTextType.comboNormalAttack); 
                   });
               }

               this.storagedDamage.Remove(uniqueID);
           });
       }

       private void DelayCall(int time, Action action)
       {
           delayActionList.Add(new DelayAction
           {
               action = action,
               actionTime = time / 1000f + currentTime,
           });
       }
       
       private void EndAllNormalAttackText()
       {
           foreach (var kvp in this.storagedFlyText)
           {
               EndNormalAttackText(kvp.Key);
           }
       }

       private float skillTextInitSize = -1;
       private float skillTextCriticalSize = -1;
       public void ShowSkillFlyText(int number, Vector3 position, int attackerTeam, bool isCritical, int unitID,SkillBase skill)
       {
           if (!showFlyText)
           {
               return;
           }
           if (CheckNeedCullByBlackScreenSkill(skill))
           {
               return;
           }
           
           EFlyTextType flyTextType = EFlyTextType.skill;
           var ani = attackerTeam == 2 ? mySkillAnim : enemySkillAnim;
           if (isCritical)
           {
               ani = attackerTeam == 2 ? myCriticalAnim : enemyCriticalAnim;
           }
           int flyTextId = (int) flyTextType;
            
           var text = PveResourceManager.GetResource(PveResourceManager.EPveResType.Hud, flyTextId);
           if (text != null)
           {
               var t = text.transform;
               t.SetParent(this.root.transform);
               t.position = position;
               t.localPosition += new Vector3(Random.Range(-flyTextSkillRangeX, flyTextSkillRangeX),
                   Random.Range(-flyTextSkillRangeY, flyTextSkillRangeY), GetFlyTextZOffset(AddToLayerMgr(unitID)));
               t.localEulerAngles = Vector3.zero;
               
               var textCom = text.GetComponentInChildren<TextMeshPro>();
               if (Mathf.Approximately(this.skillTextInitSize, -1))
               {
                   this.skillTextInitSize = textCom.fontSize;
                   this.skillTextCriticalSize = this.skillTextInitSize * this.criticalSizeRatio;
               }

               textCom.text = number.ToString();
               textCom.fontSize = isCritical ? skillTextCriticalSize : this.skillTextInitSize;
               
               var animation = text.GetComponent<Animation>();
               animation.Play(ani);
               DelayCall(2000, () =>
               {
                   RemoveFromLayerMgr(unitID);
                   PveResourceManager.RecoverResource(text, PveResourceManager.EPveResType.Hud, flyTextId);
               });
           }
       }

       public void ShowFlyTextMoney(string content, Vector3 position, float scale = 1, float moveOffset = 1)
        {
            if (!showFlyText)
            {
                return;
            }
            var text = PveResourceManager.GetResource(PveResourceManager.EPveResType.Hud, 7);
            if (text != null)
            {
                text.transform.SetParent(PveScene.pveRootTrans);
                text.transform.position = position;
                text.transform.forward = PveCameraManager.Instance.mainCamera.transform.forward;
                var textCom = text.GetComponentInChildren<Text>();
                textCom.text = content;
                textCom.gameObject.transform.localScale = PveUtils.globalRatio * 2.5f * new Vector3(scale,scale,scale);
                textCom.DOFade(0, 0.4f).SetEase(Ease.OutQuad).SetDelay(0.5f);
                textCom.color = Color.green;
                text.transform.DOMove(position + new Vector3(0, moveOffset, 0), 1f).SetEase(Ease.OutQuad).OnComplete(() =>
                {
                    PveResourceManager.RecoverResource(text,PveResourceManager.EPveResType.Hud,7);
                });
            }
        }

        public void ShowFlyTextAttributeUp(string content, Vector3 position, float scale = 1, float moveOffset = 1)
        {
            if (!showFlyText)
            {
                return;
            }
            var text = PveResourceManager.GetResource(PveResourceManager.EPveResType.Hud, 9);
            if (text != null)
            {
                text.transform.SetParent(PveScene.pveRootTrans);
                text.transform.position = position;
                text.transform.forward = PveCameraManager.Instance.mainCamera.transform.forward;
                var textCom = text.GetComponentInChildren<Text>();
                textCom.color = Color.green;
                textCom.text = content;
                //textCom.gameObject.transform.localScale = PveUtils.globalRatio * 2.5f * new Vector3(scale,scale,scale);
                textCom.DOFade(0, 0.4f).SetEase(Ease.OutQuad).SetDelay(0.5f);
                text.transform.DOMove(position + new Vector3(0, moveOffset, 0), 1f).SetEase(Ease.OutQuad).OnComplete(() =>
                {
                    PveResourceManager.RecoverResource(text,PveResourceManager.EPveResType.Hud,9);
                });
            }
        }

        public void ShowFlyText(string content, Vector3 position)
        {
            if (!showFlyText)
            {
                return;
            }
            var text = PveResourceManager.GetResource(PveResourceManager.EPveResType.Hud, 16);
            if (text != null)
            {
                text.transform.SetParent(PveScene.pveRootTrans);
                text.transform.forward = PveCameraManager.Instance.mainCamera.transform.forward;
                var textCom = text.GetComponentInChildren<YText>();
                textCom.text = content;
                var animation = text.GetComponent<Animation>();
                animation.Play(myAbsorbAnim);
                Vector3 offset = text.transform.forward * -0.3f;
                text.transform.position = position + new Vector3(Random.Range(-flyTextAbsorbRangeX,flyTextAbsorbRangeX),Random.Range(-flyTextAbsorbRangeY,flyTextAbsorbRangeY),0) + offset;
                DelayCall(2000,
                    () => { PveResourceManager.RecoverResource(text, PveResourceManager.EPveResType.Hud, 16); });
            }
        }
        
        public void ShowFlyText(string content,Vector3 position,float scale = 1,float moveOffset = 1,ETextColor colorType = ETextColor.White)
        {
            if (!showFlyText)
            {
                return;
            }
            var text = PveResourceManager.GetResource(PveResourceManager.EPveResType.Hud, 2);
            if (text != null)
            {
                text.transform.SetParent(PveScene.pveRootTrans);
                text.transform.position = position;
                text.transform.forward = PveCameraManager.Instance.mainCamera.transform.forward;
                var textCom = text.GetComponentInChildren<Text>();
                if (colorType == ETextColor.White)
                {
                    textCom.color = Color.white;
                }
                else if (colorType == ETextColor.Yellow)
                {
                    textCom.color = Color.yellow;
                }
                else if (colorType == ETextColor.Green)
                {
                    textCom.color = Color.green;
                }
                else if (colorType == ETextColor.Red)
                {
                    textCom.color = Color.red;
                }
                else if (colorType == ETextColor.Blue)
                {
                    textCom.color = Color.cyan;
                }
                textCom.text = content;
                textCom.gameObject.transform.localScale = PveUtils.globalRatio * 2.5f * new Vector3(scale,scale,scale);
                textCom.DOFade(0, 0.4f).SetEase(Ease.OutQuad).SetDelay(0.5f);
                text.transform.DOMove(position + new Vector3(0, moveOffset, 0), 1f).SetEase(Ease.OutQuad).OnComplete(() =>
                {
                    PveResourceManager.RecoverResource(text,PveResourceManager.EPveResType.Hud,2);
                });
            }
        }

        #region 飘字Z位置管理
        
        class UnitFlyTextData
        {
            public int layer;
            public int count;

            public static UnitFlyTextData operator ++(UnitFlyTextData obj)
            {
                obj.layer++;
                obj.count++;
                return obj;
            }
           
            public static UnitFlyTextData operator --(UnitFlyTextData obj)
            {
                obj.count--;
                return obj;
            }
           
            public UnitFlyTextData()
            {
                Reset();
            }

            public void Reset()
            {
                this.layer = -1;
            }
        }

        private int AddToLayerMgr(int id)
        {
            UnitFlyTextData data = null;
            if (!this.unitFlyDataDict.TryGetValue(id, out data))
            {
                data = new UnitFlyTextData();
                this.unitFlyDataDict.Add(id, data);
            }

            if (data.layer == 50)
                data.Reset();
            else
                data++;
           
            Debug.Log("[FlyTextLog] add to layer id is: " + id + " count is: " + data.count + " layer is: " +
                      data.layer);
            return data.layer;
        }

        private void RemoveFromLayerMgr(int id)
        {
            UnitFlyTextData data = null;
            if (!this.unitFlyDataDict.TryGetValue(id, out data))
                return;
           
            if (--data.count == 0)
                data.Reset();

            Debug.Log("[FlyTextLog] remove from layer id is: " + id + " count is: " + data.count + " layer is: " +
                      data.layer);
        }

        private float GetFlyTextZOffset(int layer)
        {
            return layer * -0.02f;
        }

        #endregion
    }
}